package com.nuorui.module.system.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.nuorui.common.core.code.UserErrorCode;
import com.nuorui.common.core.domain.ResponseDTO;
import com.nuorui.common.core.enums.UserTypeEnum;
import com.nuorui.common.core.exception.BizException;
import com.nuorui.common.utils.SmartBeanUtil;
import com.nuorui.module.supper.securityprotect.service.SecurityPasswordService;
import com.nuorui.module.system.mapper.DepartmentMapper;
import com.nuorui.module.system.mapper.RoleUserMapper;
import com.nuorui.module.system.mapper.UserMapper;
import com.nuorui.module.system.domain.form.UserForm;
import com.nuorui.module.system.domain.entity.DepartmentEntity;
import com.nuorui.module.system.domain.entity.UserEntity;
import com.nuorui.module.system.domain.query.UserQueryForm;
import com.nuorui.module.system.domain.vo.RoleUserVO;
import com.nuorui.module.system.domain.vo.UserVO;
import com.nuorui.module.system.manager.UserManager;
import com.nuorui.module.system.service.LoginService;
import com.nuorui.module.system.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Fred
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    @Resource
    private RoleUserMapper roleUserMapper;
    @Resource
    private DepartmentMapper departmentMapper;

    @Lazy
    @Resource
    private LoginService loginService;

    @Resource
    private SecurityPasswordService securityPasswordService;

    @Resource
    private UserManager userManager;

    @Override
    public ResponseDTO getUsersPage(Page page, UserQueryForm queryForm) {

        List<UserVO> userList = baseMapper.selectUserPage(page, queryForm);
        if (CollectionUtil.isEmpty(userList)) {
            return ResponseDTO.ok(page.setRecords(userList));
        }
        // 查询员工角色
        List<Long> userIdList = userList.stream().map(UserVO::getUserId).collect(Collectors.toList());
        List<RoleUserVO> roleUserList = userIdList.isEmpty() ? Collections.emptyList() : roleUserMapper.selectRolesByUserIdList(userIdList);
        Map<Long, List<Long>> userRoleIdListMap = roleUserList.stream().collect(Collectors.groupingBy(RoleUserVO::getUserId, Collectors.mapping(RoleUserVO::getRoleId, Collectors.toList())));
        Map<Long, List<String>> userRoleNameListMap = roleUserList.stream().collect(Collectors.groupingBy(RoleUserVO::getUserId, Collectors.mapping(RoleUserVO::getRoleName, Collectors.toList())));

        userList.forEach(e -> {
            e.setRoleIdList(userRoleIdListMap.getOrDefault(e.getUserId(), Lists.newArrayList()));
            e.setRoleNameList(userRoleNameListMap.getOrDefault(e.getUserId(), Lists.newArrayList()));
        });
        return ResponseDTO.ok(page.setRecords(userList));
    }

    /**
     * 获取某个部门的员工信息
     */
    @Override
    public ResponseDTO getUsersByDepartmentId(Long departmentId) {
        return ResponseDTO.ok(baseMapper.selectByDepartmentId(departmentId));
    }

    @Override
    public ResponseDTO saveUser(UserForm userForm) {

        // 校验登录名是否存在
        UserEntity userEntity = baseMapper.getByLoginName(userForm.getLoginName());
        if (null != userEntity) {
            return ResponseDTO.userErrorParam("登录名已存在");
        }
        // 校验电话是否存在
        userEntity = baseMapper.getByPhone(userForm.getPhone());
        if (null != userEntity) {
            return ResponseDTO.userErrorParam("手机号已存在");
        }
        // 部门是否存在
        DepartmentEntity department = departmentMapper.selectById(userForm.getDepartmentId());
        if (department == null) {
            return ResponseDTO.userErrorParam("部门不存在");
        }

        UserEntity entity = SmartBeanUtil.copy(userForm, UserEntity.class);
        // 设置密码 默认密码
        String password = securityPasswordService.randomPassword();
        entity.setLoginPwd(SecurityPasswordService.getEncryptPwd(password));

        // 保存数据
        userManager.saveUser(entity, userForm.getRoleIdList());

        return ResponseDTO.ok();
    }

    @Override
    public ResponseDTO updateUser(Long userId, UserForm userForm) {

        // 验证用户是否存在
        UserEntity userEntity = baseMapper.selectById(userId);
        if (null == userEntity) {
            throw new BizException(UserErrorCode.DATA_NOT_EXIST);
        }

        // 部门是否存在
        DepartmentEntity department = departmentMapper.selectById(userForm.getDepartmentId());
        if (department == null) {
            return ResponseDTO.userErrorParam("部门不存在");
        }

        // 检查唯一性
        ResponseDTO<String> checkResponse = checkUniqueness(userId, userForm.getLoginName(), userEntity.getPhone(), userEntity.getEmail());
        if (!checkResponse.getOk()) {
            return checkResponse;
        }

        UserEntity entity = SmartBeanUtil.copy(userForm, UserEntity.class);
        // 不更新密码
        entity.setLoginPwd(null);
        // 更新数据
        userManager.updateUser(entity, userForm.getRoleIdList());
        // 清除员工缓存
        loginService.clearLoginUserCache(userId);

        return ResponseDTO.ok();
    }

    private ResponseDTO<String> checkUniqueness(Long userId, String loginName, String phone, String email) {

        UserEntity existEntity = baseMapper.getByLoginName(loginName);
        if (null != existEntity && !Objects.equals(existEntity.getUserId(), userId)) {
            return ResponseDTO.userErrorParam("登录名重复");
        }

        existEntity = baseMapper.getByPhone(phone);
        if (null != existEntity && !Objects.equals(existEntity.getUserId(), userId)) {
            return ResponseDTO.userErrorParam("手机号已存在");
        }

        existEntity = baseMapper.getByEmail(email);
        if (null != existEntity && !Objects.equals(existEntity.getUserId(), userId)) {
            return ResponseDTO.userErrorParam("邮箱账号已存在");
        }
        return ResponseDTO.ok();
    }

    @Override
    public ResponseDTO updateDisable(Long userId) {
        if (null == userId) {
            return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
        }
        UserEntity entity = baseMapper.selectById(userId);
        if (null == entity) {
            return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
        }
        baseMapper.updateDisable(userId, !entity.getIsDisabled());

        if (entity.getIsDisabled()) {
            // 强制退出登录
            StpUtil.logout(UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StrUtil.COLON + userId);
        }
        return ResponseDTO.ok();
    }

    @Override
    public ResponseDTO<String> resetPassword(Long userId) {
        String password = securityPasswordService.randomPassword();
        baseMapper.updatePassword(userId, SecurityPasswordService.getEncryptPwd(password));
        return ResponseDTO.ok(password);
    }

    @Override
    public ResponseDTO<String> batchDelete(List<Long> userIdList) {
        if (CollectionUtil.isEmpty(userIdList)) {
            return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
        }

        // 删除用户记录
        int deletedCount = baseMapper.deleteBatchIds(userIdList);
        if (deletedCount == 0) {
            return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
        }
        // 批量注销登录（假设 StpUtil 不支持批量，使用stream并行处理）
        userIdList.parallelStream()
                .map(id -> UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StrUtil.COLON + id)
                .forEach(StpUtil::logout);

        return ResponseDTO.ok();
    }
}
